getOrders <- function(store, newRowList, currentPos, info, params) {
  
  allzero  <- rep(0,length(newRowList)) # used for initializing vectors
  
  ################################################
  # You do not need to edit this part of the code
  # that initializes and updates the store
  ################################################
  if (is.null(store)) 
    store <- initStore(newRowList)
  else
    store <- updateStore(store, newRowList)
  ################################################
  
  pos <- allzero
  
  ################################################
  # This next code section is the only one you
  # need to edit for getOrders
  #
  # The if condition is already correct:
  # you should only start computing the moving 
  # averages when you have enough close prices 
  # for the long moving average 
  ################################################
  if (store$iter > params$lookbacks$long) {
    # ENTER STRATEGY LOGIC HERE
    for(i in 1:2){
      current_close=last(store$cl[[i]])
      close=store$cl[[i]]
      close_prices=as.xts(close) # get close prices
      tma_list=getTMA(close_prices,params$lookbacks) # calculate TMA
      pos[[i]]=getPosSignFromTMA(tma_list)*getPosSize(current_close) # set pos with TMA pos sign
    }
    
    
    # You will need to get the current_close
    # either from newRowList or from store$close
    library(TTR)
    # You will also need to get close_prices 
    # from store$cl
    
    # With these you can use getTMA, getPosSignFromTMA
    # and getPosSize to assign positions to the vector pos
  }
  
  ################################################
  # You do not need to edit this part of the code
  # that initializes and updates the store
  ################################################
  marketOrders <- -currentPos + pos
  
  return(list(store=store,marketOrders=marketOrders,
              limitOrders1=allzero,limitPrices1=allzero,
              limitOrders2=allzero,limitPrices2=allzero))
}

########################################################################
# The following function should be edited to complete steps 1 to 3
# of comp22 assignment 2

getTMA <- function(close_prices, lookbacks) {
  
  # close_prices should be an xts with a column called "Close"
  
  # lookbacks should be list with exactly three elements:
  # lookbacks$short  is an integer
  # lookbacks$medium is an integer
  # lookbacks$long   is an integer
  
  # It should be the case that:
  # lookbacks$short < lookbacks$medium < lookbacks$long
  
  ####################################################################
  # First we implement checks on the arguments
  
  # Replace TRUE to
  # check that lookbacks contains named elements short, medium and long
  if (isFALSE("long"%in% names(lookbacks) && "short"%in% names(lookbacks) && "medium"%in% names(lookbacks)))
    stop("E01: At least one of \"short\", \"medium\", \"long\" is missing from names(lookbacks)")
  
  # Replace TRUE to
  # check that the elements of lookbacks are all integers
  if (is.integer(class(lookbacks$short))&&is.integer(class(lookbacks$medium))&&is.integer(class(lookbacks$long)))
    stop("E02: At least one of the lookbacks is not an integer according to is.integer()")
  
  # Replace TRUE to
  # check that lookbacks$short < lookbacks$medium < lookbacks$long
  if (isFALSE(lookbacks$short < lookbacks$medium && lookbacks$medium < lookbacks$long)) 
    stop("E03: The lookbacks do not satisfy lookbacks$short < lookbacks$medium < lookbacks$long")
  
  # Replace TRUE to
  # check that close_prices is an xts
  if (isTRUE(class(close_prices)[1]!="xts"))
    stop("E04: close_prices is not an xts according to is.xts()")
  
  # Replace TRUE to
  # check that close_prices has enough rows
  if (nrow(close_prices) < max(lookbacks$short,lookbacks$medium,lookbacks$long))
    stop("E05: close_prices does not enough rows")
  
  # Replace TRUE to
  # check that close_prices contains a column called "Close"
  if (isTRUE(colnames(close_prices)!="Close"))
    stop("E06: close_prices does not contain a column \"Close\"")
  
  ret=numeric(0)
  for(i in 1:length(lookbacks))
  {
    ret[i] <-as.numeric(last(SMA(close_prices,n=lookbacks[[i]])))  # get last close prices
  }
  retlist <-list(short=ret[1],medium=ret[2],long=ret[3]) # generate the list as required
  # You need to replace the assignment to ret so that the 
  # returned object:
  #    - is a list 
  #    - has the right names (short, medium, long), and
  #    - contains numeric and not xts objects
  #    - and contains the correct moving average values, which should 
  #      have windows of the correct sizes which should all end in the 
  #      same period which should be the last row of close_prices
  return(retlist)
  
}

getPosSignFromTMA <- function(tma_list) {
  # This function takes a list of numbers tma_list 
  # with three elements called short, medium, and long.
  
  # These three numbers correspond to the SMA values for 
  # a short, medium and long lookback, respecitvely.
  
  # Note that if both this function and get TMA 
  # are correctly implemented then the 
  # following should work if the inputs close_prices 
  # and lookbacks are of the correct form:
  # getPositionFromTMA(getTMA(close_prices,lookbacks))
  
  # This function should return a single number that is:
  #        1 if the short SMA < medium SMA < long SMA
  #       -1 if the short SMA > medium SMA > long SMA
  #        0 otherwise
  if(tma_list$short < tma_list$medium && tma_list$medium < tma_list$long){
    return(1)
  }else if(tma_list$short > tma_list$medium && tma_list$medium > tma_list$long){
    return(-1)
  }else{
    return(0)
  }
  
  
}

getPosSize <- function(current_close,constant=1000) {
  # This function should return (constant divided
  # by current_close) rounded down to the nearest 
  # integer, i.e., due the quotient and then take 
  # the floor.
  return(floor(constant/current_close))
}

userName='sgyxu27'

getInSampleResult <- function() {
  sMult <- 0.2 
  period=getInSamplePeriod(userName)
  dataList<- getData(directory="A2")
  dataList <-lapply(dataList, function(x)x[period[1]:period[2]])
  lookbacks <-list(short=as.integer(10),medium=as.integer(20),long=as.integer(30))
  
  #series=1:length(dataList)
  #newRowList=getRowList(dataList,1)
  #params <-list(lookbacks=lookbacks,sdParam=1,series=series)
  params <-list(lookbacks=lookbacks)
  
  results <- backtest(dataList, getOrders, params, sMult)
  pfolioPnL <- plotResults(dataList,results)
  return(pfolioPnL$fitAgg)
  
  #results <- backtest(dataList, getOrders, params, sMult =0.2)
  #pfolioPnL <- plotResults(dataList,results)
  # Here you should replace the return value 0 with
  # the PD ratio for the following lookbacks
  # short: 10
  # medium: 20
  # long: 30
  # when the strategy is run on your 
  # username-specific in-sample period
  # DO NOT PUT THE ACTUAL CODE TO COMPUTE THIS RETURN VALUE HERE
}

getInSampleOptResult <- function() {
  period=getInSamplePeriod(userName)
  dataList<- getData(directory="A2")
  dataList <-lapply(dataList, function(x)x[period[1]:period[2]])
  
  short <-seq(from=100,to=110,by=5)
  medium<-seq(from=105,to=120,by=5)
  long <-seq(from=110,to=130,by=5)
  
  #time<-matrix(0,28,3)
  sMult <- 0.2 # slippage multiplier
  
  numOfSeries=length(dataList)
  time <- matrix(0,28,3)
  
  row=1
  for(z in 1:length(long))
    for(i in 1:length(short))
      for(j in 1:length(medium))
        if(short[i]<medium[j] && medium[j]< long[z]){
          time[row,]=c(as.integer(short[i]),as.integer(medium[j]),as.integer(long[z]))
          row=row+1
        }
  
  colnames(time)=c("short","medium","long")
  resultsMatrix <- matrix(nrow=nrow(time),ncol=4)
  
  colnames(resultsMatrix) <- c("short","medium","long","PDratio")
  pfolioPnLList <- vector(mode="list",length=nrow(time))
  count <- 1
  sMult<-0.2
  for (i in 1:nrow(time)) {
    newRowList=getRowList(dataList,count)
    short=as.integer(time[i,1]);medium=as.integer(time[i,2]);long=as.integer(time[i,3]);
    lookbacks <-list(short=short,medium=medium,long=long)
    params <-list(lookbacks=lookbacks,sdParam=1,series=1:numOfSeries,posSizes=rep(1,getPosSize(newRowList[[1]]$Close)))
    results <- backtest(dataList, getOrders, params, sMult)
    pfolioPnL <- plotResults(dataList,results)
    resultsMatrix[count,] <- c(lookbacks[[1]],lookbacks[[2]],lookbacks[[3]],pfolioPnL$fitAgg)
    pfolioPnLList[[count]]<- pfolioPnL
    cat("Just completed",count,"out of",time,"\n")
    print(resultsMatrix[count,])
    count <- count + 1
  }
  
  
  # Here you should replace the return value 0 with
  # the best PD ratio that can be found for the pre-defined
  # parameter ranges 
  # (see the Assignment 2 handout for details of those ranges)
  # and your username-specific in-sample period
  # DO NOT PUT THE ACTUAL CODE TO COMPUTE THIS RETURN VALUE HERE
  print(resultsMatrix[order(resultsMatrix[,"PDratio"]),])
  return(max(resultsMatrix[,4]))
  
}

########################################################################
# The functions below do NOT need to be edited for comp226 assignment 2

initClStore  <- function(newRowList) {
  clStore <- lapply(newRowList, function(x) x$Close)
  return(clStore)
}
updateClStore <- function(clStore, newRowList) {
  clStore <- mapply(function(x,y) rbind(x,y$Close),clStore,newRowList,SIMPLIFY=FALSE)
  return(clStore)
}
initStore <- function(newRowList,series) {
  return(list(iter=1,cl=initClStore(newRowList)))
}
updateStore <- function(store, newRowList) {
  store$iter <- store$iter + 1
  store$cl <- updateClStore(store$cl,newRowList) 
  return(store)
}


